home *** CD-ROM | disk | FTP | other *** search
- // Copyright (c)1996 Ray Dream, Inc. All Rights Reserved.
- /* $Id: COMSand.cpp 1.13 1997/07/07 16:58:03 damien Exp $ */
-
- ////////////////////////////////////////////////////////////////////////
- // Post renderer Example : Sand //
- //--------------------------------------------------------------------//
- // Implementation of the Sand Interface //
- ////////////////////////////////////////////////////////////////////////
-
- #ifndef __COMSand__
- #include "COMSand.h"
- #endif
-
- #ifndef __SandDLL__
- #include "SandDLL.h"
- #endif
-
- // Failure Handling
- #ifndef __3DCOFAIL__
- #include "3DCoFail.h"
- #endif
-
- #ifndef __3DBSTYPE__
- #include "3DBSType.h"
- #endif
-
- #ifndef __I3DSHUTI__
- #include "I3DShuti.h"
- #endif
-
- #include "StdLib.h"
-
- #undef INTERFACE
- #define INTERFACE Sand
-
- IShUtilities* sandShellUtilities;
-
- long RandomColor(long value) {
- if ((rand()*0xFE/RAND_MAX) >= value) {
- return 0;
- }
- else {
- return 0xFF;
- }
- }
-
- // Constructor / Destructor of the C++ Object :
- Sand::Sand() {
- fCRef=0; // Reference Counter
- }
-
- Sand::~Sand() {
- global_count_Obj--;
- }
-
- // IUnknown Interface :
- HRESULT Sand::QueryInterface(THIS_ REFIID riid,LPVOID* ppvObj) {
- *ppvObj=NULL;
-
- // The Sand knows the interfaces of the parent Objects
- if (IsEqualIID(riid, IID_IUnknown))
- *ppvObj=(LPVOID)this;
- else if (IsEqualIID(riid, IID_I3DExPostRenderer))
- *ppvObj=(LPVOID)this;
- else if (IsEqualIID(riid, IID_I3DExDataExchanger))
- *ppvObj=(LPVOID)this;
- else if (IsEqualIID(riid, IID_I3DExtension))
- *ppvObj=(LPVOID)this;
-
- // we must add reference if we return an interface
- if (*ppvObj!=NULL) {
- ((LPUNKNOWN)*ppvObj)->AddRef();
- return NOERROR;
- }
- else {
- return ResultFromScode(E_NOINTERFACE);
- }
- }
-
- ULONG Sand::AddRef(THIS) {
- return fCRef++;
- }
-
- ULONG Sand::Release(THIS) {
- ULONG UnreleaseObject=fCRef--;
-
- if (fCRef==0)
- delete this; // No reference left, so destroy the object
-
- return UnreleaseObject;
- // local variable used, because fCRef can be destroyed before.
- }
-
- // I3DExtension methods :
- I3DExtension* Sand::Clone(THIS) {
- Sand* theClone = new Sand;
- if (theClone) {
- theClone->AddRef();
- }
- return theClone;
- }
-
- HRESULT Sand::ShellUtilitiesInit(THIS_ IShUtilities* shellUtilities) {
- // not called anymore
- return NOERROR;
- }
-
- // I3DExDataExchanger methods :
- ExtensionDataMap* Sand::GetExtensionDataMap(THIS) {
- return NULL;
- }
-
- void* Sand::GetExtensionDataBuffer(THIS) {
- return 0; // used by the shell to set the new parameters
- }
-
- HRESULT Sand::ExtensionDataChanged(THIS) {
- return NOERROR;
- }
-
- HRESULT Sand::HandleEvent(THIS_ ULONG SourceID) {
- return ResultFromScode(E_NOTIMPL);
- }
-
- short Sand::GetResID(THIS) {
- return 128; // this is the view ID in the resource file.
- }
-
- // I3DExPostRenderer methods :
- void Sand::Filter (THIS_ I3DShScene* theScene,IShRasterOffscreen* theImage,IUnknown** theBuffers,
- IShGraphicDevice* gd, /*TExternalRenderer*/void* renderer, void* renderHelper) {
- ULONG depth;
- RECT3D BRect;
- BRect.top = 0;
- BRect.left = 0;
- BRect.right = 32000;
- BRect.bottom = 32000;
-
- BufferChunk* aChunk=0;
- LRECT3D* aClip=new LRECT3D;
- LRECT3D* cursorClip=new LRECT3D;
- RECT3D* shortRect=new RECT3D;
- ULONG chunkH, chunkV, rowBytes;
-
- theImage->GetChunkInfo(&chunkH, &chunkV, &rowBytes, &depth);
- if (depth == 32) {
- // creating the cursor
- IShRasterOffscreen* theCursor;
- sandShellUtilities->CoCreateInstance(CLSID_StandardRasterOffscreen,0,0,IID_IShRasterOffscreen,(void**)&theCursor);
- theCursor->InitOffscreen((short)chunkH, (short)chunkV, (short)depth);
- IEnumChunk* FirstChunk = theCursor->EnumChunks(&BRect);
- FirstChunk->Next(1,&aChunk,0);
- FirstChunk->Release();
- theCursor->GetChunkRect(aChunk, shortRect);
- cursorClip->top=shortRect->top;
- cursorClip->left=shortRect->left;
- cursorClip->bottom=shortRect->bottom;
- cursorClip->right=shortRect->right;
- theCursor->LockChunk(aChunk);
- long* PCurChunk;
- PCurChunk = (long*)(theCursor->GetChunkData(aChunk));
- ULONG i,j;
- for (i=0; i<chunkV; i++) {
- for (j=0; j<chunkH; j++) {
- *(PCurChunk++)=(((i^j)&8)==0?0x0000000:0x0FFFF00); // square black or yellow each 8 pixels
- }
- }
- theCursor->UnlockChunk(aChunk);
-
- IEnumChunk* iter = theImage->EnumChunks(&BRect);
- for (; (iter->Next(1,&aChunk,0)) == NO_ERROR; ) {
-
- theImage->GetChunkRect(aChunk, shortRect);
- aClip->top=shortRect->top;
- aClip->left=shortRect->left;
- aClip->bottom=shortRect->bottom;
- aClip->right=shortRect->right;
- shortRect->top=cursorClip->top;
- shortRect->left=cursorClip->left;
- shortRect->bottom=cursorClip->bottom;
- shortRect->right=cursorClip->right;
- gd->DrawOffscreen(theCursor, *shortRect, *aClip);
- theImage->LockChunk(aChunk);
- long* data = (long*)theImage->GetChunkData(aChunk);
- for (short vv = aClip->top; vv< aClip->top + chunkV; vv++) {
- theImage->SetPosition(aClip->left, vv);
- for (short hh = aClip->left; hh< aClip->left + chunkH; hh++) {
- long color;
- theImage->Get(&color);
- (*data) = RandomColor(color & 0xFF) + (RandomColor((color>>8) & 0xFF)<<8) + (RandomColor((color>>16) & 0xFF)<<16);
-
- theImage->GoRight();
- data++;
- } // for hh
- } // for vv
- theImage->UnlockChunk(aChunk);
- shortRect->top=aClip->top;
- shortRect->left=aClip->left;
- shortRect->bottom=aClip->bottom;
- shortRect->right=aClip->right;
- gd->DrawOffscreen(theImage, *shortRect, *aClip);
-
- } // for iter
- iter->Release();
- theCursor->Release();
- } // if depth
-
- }
-
- enum {kDistance=1, kPositionX=2, kPositionY=4, kPositionZ=8,
- kNormalX=0x10, kNormalY=0x20, kNormalZ=0x40,
- kAlpha=0x80, kIndex=0x100, kSurfaceU=0x200, kSurfaceV=0x400};
- enum {kNumberOfGBuffers=20};
-
- void Sand::GetBufferNeeds (THIS_ /*RenderFilterNeeds&*/long* needs, /*TExternalRenderer*/void* renderer) {
- *needs = 0;
- }
-
-